package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.config.HighlightResultMapper;
import cn.itsource.ymcc.doc.CourseDoc;
import cn.itsource.ymcc.dto.Bucket;
import cn.itsource.ymcc.dto.CourseSearchDTO;
import cn.itsource.ymcc.repository.CourseElasticsearchRepository;
import cn.itsource.ymcc.service.ICourseSearchService;
import cn.itsource.ymcc.vo.AggPageList;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CourseSearchServiceImpl implements ICourseSearchService {
    @Autowired
    private ElasticsearchRestTemplate template;
    @Autowired
    private CourseElasticsearchRepository courseElasticsearchRepository;
    @Autowired
    private HighlightResultMapper highlightResultMapper;
    @Override
    public void save(CourseDoc doc) {
        courseElasticsearchRepository.save(doc);
    }

    @Override
    public void delete(Long id) {
        courseElasticsearchRepository.deleteById(id);
    }

    @Override // 查询页面
    public AggPageList<CourseDoc> search(CourseSearchDTO dto) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withPageable(PageRequest.of(dto.getPage()-1,dto.getRows()));
        if (StringUtils.isNotEmpty(dto.getSortField())){
            String sortField = dto.getSortField();
            switch (sortField){
                case "xl" : sortField = "saleCount";
                    break;
                case "xp" : sortField = "onlineTime";
                    break;
                case "pl" : sortField = "commentCount";
                    break;
                case "jg" : sortField = "price";
                    break;
                case "rq" : sortField = "viewCount";
                    break;
            }
            String sortType = dto.getSortType().toLowerCase();
            if (sortType.equals("asc")){
                builder.withSort(new FieldSortBuilder(sortField).order(SortOrder.ASC));
            } else {
                builder.withSort(new FieldSortBuilder(sortField).order(SortOrder.DESC));
            }
        }


        BoolQueryBuilder query = QueryBuilders.boolQuery();

        if (StringUtils.isNotEmpty(dto.getKeyword())){
            query.must(QueryBuilders.matchQuery("name",dto.getKeyword()));
        }

        if (StringUtils.isNotEmpty(dto.getGradeName())){
            query.filter(QueryBuilders.termQuery("gradeName",dto.getGradeName()));
        }



        if (dto.getPriceMax() != null){
            query.filter(QueryBuilders.rangeQuery("price").lte(dto.getPriceMax()));
        }

        if (dto.getPriceMin() != null){
            query.filter(QueryBuilders.rangeQuery("price").gte(dto.getPriceMin()));
        }

        builder.withQuery(query);
        // 字段高亮处理
        HighlightBuilder.Field  highlightField = new HighlightBuilder.Field("name")
                .preTags("<span style='color:red'>")
                .postTags("</span>");
        builder.withHighlightFields(highlightField);

        //聚合查询
        TermsAggregationBuilder agg = AggregationBuilders.terms("gradeNameAgg").field("gradeName");

        builder.addAggregation(agg);
        NativeSearchQuery searchQuery = builder.build();

        //2.调用repository的search方法查询
        //Page<CourseDoc> page = courseElasticsearchRepository.search(builder.build());
        AggregatedPage<CourseDoc> list = template.queryForPage(searchQuery, CourseDoc.class, highlightResultMapper);

        Map<String, List<Bucket>> aggrMap = new HashMap<>();

        //遍历聚合结果
        Aggregations aggregations = list.getAggregations();

        Map<String, Aggregation> stringAggregationMap = aggregations.asMap();

        Set<Map.Entry<String, Aggregation>> entries = stringAggregationMap.entrySet();
        List<Bucket> list1 = new ArrayList<>();
        entries.forEach(e->{
            //集合的名字
            String key = e.getKey();
            //集合的值的处理
            ParsedStringTerms value = (ParsedStringTerms)e.getValue();

            List<? extends Terms.Bucket> buckets = value.getBuckets();
//
//            //使用lomda 把  List<StringTerms.Bucket>  转成  List<AggrTermsVo>
//            List<Bucket> aggrTermsVos = buckets.stream().map(bucket -> {
//                return new Bucket(bucket.getKeyAsString(), bucket.getDocCount());
//            }).collect(Collectors.toList());
            for (Terms.Bucket bucket : buckets) {
                String key1 = bucket.getKeyAsString();
                long docCount = bucket.getDocCount();
                list1.add(new Bucket(key1,docCount));
            }
            aggrMap.put(key, list1);
        });

        //Page<CourseDoc> list = courseElasticsearchRepository.search(searchQuery);
        return new AggPageList<CourseDoc>(list.getTotalElements(),list.getContent(),aggrMap);
        //return new PageList<CourseDoc>(list.getTotalElements(),list.getContent());
    }


}
